//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy
//===============================================================================

using System;
using System.Globalization;

namespace EntLibContrib.Logging.Parser
{
	/// <summary>
	/// Encapsulates the logic for parsing the time stamp text from a log file.
	/// </summary>
	public class TimeStampParserFraction : ITimeStampParser
	{
		#region Constants
		/// <summary>
		/// TimeStamp format
		/// </summary>
		public const string TimeStampFormat = "o";
		#endregion

		#region Fields
		private IFormatProvider formatProvider;
		#endregion

		#region Properties
		/// <summary>
		/// Specify time stamp format for month-day or day-month order, etc.
		/// </summary>
		/// <value>The format provider.</value>
		public IFormatProvider FormatProvider
		{
			get { return formatProvider; }
			set { formatProvider = value; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Constructor to initialize a new instance of the class.
		/// Sets <see cref="FormatProvider"/> to <see cref="CultureInfo.CurrentCulture"/>
		/// </summary>
		public TimeStampParserFraction()
		{
			this.formatProvider = CultureInfo.CurrentCulture;
		}

		/// <summary>
		/// Constructor to initialize a new instance of the class.
		/// </summary>
		/// <param name="formatProvider">time stamp format provider for month-day or day-month order, etc.</param>
		public TimeStampParserFraction(IFormatProvider formatProvider)
		{
			this.formatProvider = formatProvider;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Parse the time stamp text from a log file.
		/// </summary>
		/// <param name="timeStampText">time stamp text</param>
		/// <returns>date and time</returns>
		public DateTime ParseTimeStamp(string timeStampText)
		{
			//return DateTime.ParseExact(stringTime, TimeStampFormat, formatProvider).ToUniversalTime();
			//was slow (even slower than DateTime.Parse, which is slower than DateTime.ParseExact)
			//FractionTimeStamp elapsed seconds = 1.107
			//DefaultTimeStamp elapsed seconds = 1.065
			//FormatTimeStamp elapsed seconds = 1.062
			//new DateTime(int.Parse is faster than the others
			//FractionTimeStamp elapsed seconds = 1.039

			// 0    0  0  1  1  1  2
			// 01234567890123456789012
			// yyyy-MM-ddTHH:mm:ss.fff
			string substring;
			substring = timeStampText.Substring(00, 4);
			int y = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(05, 2);
			int M = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(08, 2);
			int d = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(11, 2);
			int H = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(14, 2);
			int m = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(17, 2);
			int s = int.Parse(substring, CultureInfo.CurrentCulture);
			substring = timeStampText.Substring(20, 3);
			int f = int.Parse(substring, CultureInfo.CurrentCulture);
			return new DateTime(y, M, d, H, m, s, f);
		}
		#endregion
	}
}
